from PySide6.QtGui import QStandardItemModel, QStandardItem
from PySide6.QtWidgets import QTableView, QHeaderView, QGraphicsProxyWidget, QPushButton, QVBoxLayout, QWidget

from 程序核心代码.mvvm重构.基础定义.基础图形项.基础图形组件.子组件.通用基类.模型定义 import 组件模型基类, 组件节点图形项基类


class 表格组件模型(组件模型基类):
    def __init__(self,表格列名:list, 表格数据:list):
        super().__init__("表格组件",表格列名=表格列名, 表格数据=表格数据)

class 表格组件图形项(组件节点图形项基类):
    def __init__(self,模型):
        super().__init__(模型)
    def 组件初始化(self):
        self.组件=数据表格组件(self.图形项属性.get("表格列名"),self.图形项属性.get("表格数据"))
        self.注册属性触发函数("表格数据", self.更新表格数据)
        self.注册属性触发函数("表格列名", self.更新表格列名)
        self.组件.表格数据回调函数 = self.表格数据回调函数

    def 更新表格列名(self):
        self.组件.表格列名= self.图形项属性.get("表格列名")
        self.组件.设置表格列名()
    def 更新表格数据(self):
        self.组件.表格数据= self.图形项属性.get("表格数据")
        self.组件.更新模型数据()
    def 表格数据回调函数(self):
        self.设置图形项属性("表格数据",self.组件.表格数据)


class 数据表格组件(QGraphicsProxyWidget):
    def __init__(self, 表格列名:list, 表格数据:list ):
        """初始化表格组件
        表格列名:list 表格列名列表 ["键", "值"]
        表格数据:list 表格数据列表 [["key1", "value1"], ["key2", "value2"]]  二维列表 第一层为行，第二层为行内容  可用None表示空单元格
        """

        super().__init__()
        self.表格列名 = 表格列名
        self.表格数据 = 表格数据
        # 创建主小部件和布局
        self.主小部件 = QWidget()
        self.布局 = QVBoxLayout(self.主小部件)
        # 创建QTableView
        self.表格视图 = QTableView()
        # 初始化模型
        self.表格模型 = QStandardItemModel()
        # 设置数据
        self.设置数据(表格数据)
        if self.表格列名:
            self.表格模型.setHorizontalHeaderLabels(表格列名)
        self.表格视图.setModel(self.表格模型)
        # 设置列宽自动填充
        self.表格视图.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.表格视图.setSelectionBehavior(QTableView.SelectItems)
        self.表格视图.setSelectionMode(QTableView.ExtendedSelection)
        # 将QTableView添加到布局
        self.布局.addWidget(self.表格视图)
        # 创建添加行的按钮并绑定功能
        self.添加行按钮 = QPushButton("添加行")
        self.添加行按钮.clicked.connect(self.添加行)
        self.布局.addWidget(self.添加行按钮)
        # 将主小部件设置为代理小部件的部件
        self.setWidget(self.主小部件)
        self.表格数据回调函数 = None
    def 初始化模型(self):
        """初始化模型"""
        #起始接口.表格模型 = QStandardItemModel()
        if self.表格列名:
            #检查列名与数据长度是否一致
            if len(self.表格列名) != len(self.表格数据[0]):
                raise ValueError("表格列名与数据长度不一致")
            self.更新模型数据()
        self.表格模型.itemChanged.connect(self.更新表格数据)

    def 更新模型数据(self):
        """设置表格数据"""
        self.表格模型.clear()
        self.设置表格列名()
        for 行号, 行数据 in enumerate(self.表格数据):
            for 列号, 列数据 in enumerate(行数据):
                self.表格模型.setItem(行号, 列号, QStandardItem(列数据))
    def 更新表格数据(self,修改内容):
        """获取表格数据"""
        self.表格数据= []
        行数 = self.表格模型.rowCount()
        列数 = self.表格模型.columnCount()
        for 行号 in range(行数):
            行数据 = []
            for 列号 in range(列数):
                项 = self.表格模型.item(行号, 列号)
                行数据.append(项.text())
            self.表格数据.append(行数据)
        self.表格数据回调函数()
    def 清空内容(self):
        # 获取当前行数
        row_count = self.表格模型.rowCount()
        if row_count > 0:
            # 删除所有行
            self.表格模型.removeRows(0, row_count)
    def 设置表格列名(self):
        """设置表格列名"""
        self.表格模型.setHorizontalHeaderLabels(self.表格列名)

    def 获取单元格内容(self, 行, 列):
        """获取指定单元格的内容"""
        项 = self.表格模型.item(行, 列)
        return 项.text() if 项 else ""

    def 设置单元格内容(self, 行, 列, 内容):
        """设置指定单元格的内容"""
        项 = QStandardItem(内容)
        self.表格模型.setItem(行, 列, 项)

    def 添加行(self):
        """在表格中添加一个空白行"""
        行号 = self.表格模型.rowCount()
        self.表格模型.insertRow(行号)
        self.自动调整大小()

    def 设置数据(self, 数据):
        """将数据直接加载到现有模型中，而不是替换模型"""
        self.表格模型.clear()
        # 设置标题
        self.表格模型 = 数据
        self.表格视图.setModel(self.表格模型)
        self.表格模型.itemChanged.connect(self.同步触发器)
        self.自动调整大小()

    def 同步触发器(self, item):
        """处理模型中的数据变更事件，获取行、列和内容"""
        行 = item.row()
        列 = item.column()
        内容 = item.text()
        # 触发数据变更信号，包含行、列和新内容
        操作类型 = "修改"
        if self.同步函数:
            self.同步函数(行, 列, 内容, 操作类型)
        self.自动调整大小()

    def 自动调整大小(self):
        """根据内容自动调整表格组件的大小"""
        # 计算表格视图的合适高度
        行数 = self.表格模型.rowCount()
        列数 = self.表格模型.columnCount()
        行高 = self.表格视图.verticalHeader().defaultSectionSize() if 行数 > 0 else 0
        标题高度 = self.表格视图.horizontalHeader().height()
        按钮高度 = self.添加行按钮.height()

        总高度 = 行数 * 行高 + 标题高度 + 按钮高度

        # 计算表格视图的合适宽度
        列宽 = self.表格视图.horizontalHeader().defaultSectionSize() if 列数 > 0 else 0
        总宽度 = 列数 * 列宽

        # 设置表格视图的大小
        self.表格视图.setFixedSize(总宽度, 总高度)

        # 调整主小部件的大小
        self.主小部件.adjustSize()
